package robots.domain;

import java.util.Random;

import robots.excepcions.DineroEnNullException;
import robots.excepcions.DineroInsuficienteException;
import robots.excepcions.RobotEnNullException;

public class CampoDeBatalla {
	
	/**
	 * 
	 * @param robotLocal
	 * @param robotVisitante
	 * @param apuesta
	 * @return	Un ArrayList con los siguientes valores: [ integer::esGanadorLocal(1 si gana. 0 si pierde) , integer::desgaste , integer/null::ganancia]
	 * @throws RobotEnNullException 
	 * @throws DineroInsuficienteException 
	 * @throws DineroEnNullException 
	 */
	public Resultado competir(Robot robotLocal, Robot robotVisitante, Integer apuesta) throws DineroInsuficienteException, RobotEnNullException, DineroEnNullException{
		
		validarPuedeCompetir(robotLocal, robotVisitante, apuesta);
		Resultado resultado = new Resultado();
		resultado.setApuesta(apuesta);
		if (ganoElLocal(robotLocal, robotVisitante)){
			Integer ganancia= this.calcularGanancia(apuesta, robotLocal, robotVisitante);
			robotLocal.ganaste(ganancia);
			resultado.setGanador(robotLocal);
			resultado.setGanancia(ganancia);
			resultado.ganoElLocal(true);
			
		} else {
			robotLocal.getJugador().cobrar(apuesta);
			resultado.setGanador(robotVisitante);
		}
		Integer desgaste= this.calcularPorcentajeDesgasteDeRobot(robotLocal, robotVisitante);
		robotLocal.aumnetarDanioEn(desgaste);
		resultado.setDesgaste(desgaste);
		return resultado;
	}

	public void validarPuedeCompetir(Robot robotLocal, Robot robotVisitante,Integer apuesta) 
								throws DineroInsuficienteException, RobotEnNullException, DineroEnNullException{
		if (apuesta == null){
			throw new DineroEnNullException();
		}
		if (robotLocal == null || robotVisitante == null){
			throw new RobotEnNullException();
		}
		
		if (!robotLocal.podesCompetirPorDinero(apuesta)){
			throw new DineroInsuficienteException();
		}
		
	}
	
	/**
	 * Para determinar si el local es el ganador se realiza el siguiente calculo:
	 * random(0,1) <= poderPropio / (poderPropio + poderOponente).
	 * El poder se considera como el "poder efectivo" del robot.
	 */
	private Boolean ganoElLocal(Robot robotLocal, Robot robotVisitante){
		return Math.random() <= 
					(double) robotLocal.getPoderEfectivo() / (robotLocal.getPoderEfectivo() + robotVisitante.getPoderEfectivo());
	}

	/**
	 * Para calcular la ganancia del jugador si gano se utiliza el siguiente calculo:
	 * apuesta * (poderPropio + poderOponente) / poderPropio.
	 */
	public Integer calcularGanancia(Integer apuesta, Robot robotLocal, Robot robotVisitante){
		return apuesta * (robotLocal.getPoderEfectivo() + robotVisitante.getPoderEfectivo() ) / robotLocal.getPoderEfectivo();
	}
	
	/**
	 * Para calcular el porcentaje de desgaste se realiza el siguiente calculo:
	 * random(0,20) * poderOponente / (poderPropio + poderOponente). 
	 */
	private Integer calcularPorcentajeDesgasteDeRobot(Robot robotLocal, Robot robotVisitante){
		return new Random().nextInt(20) * robotVisitante.getPoderEfectivo() / (robotLocal.getPoderEfectivo() + robotVisitante.getPoderEfectivo());
	}
	
	
	
}
